package com.yfve.eol.activity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.yfve.eol.Constants;
import com.yfve.eol.EolApplication;
import com.yfve.eol.R;
import com.yfve.eol.util.Util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TouchTestActivity extends Activity {
    private static final String TAG = "Eol:TouchTestActivity";
    private static final int TOUCH_ACTION_TAP = 1;
    private static final int TOUCH_ACTION_PRESS_AND_HOLD = 2;
    private static final int TOUCH_ACTION_PAN = 3;

    private static final int MULTI_POINTER_COUNT = 5;

    private static final int SCROLL_THRESHOLD = 20;

    private static int sLastTouchAction = -1;
    private static List<PointF> sMultiPoints = new ArrayList<>(MULTI_POINTER_COUNT);
    @SuppressLint("StaticFieldLeak")
    private static TouchTestActivity sInstance = null;
    GestureDetector mTouchGestureDetector = new GestureDetector(EolApplication.getAppContext(), new GestureDetector.OnGestureListener() {
        private float mTotalDistanceX;
        private float mTotalDistanceY;

        @Override
        public boolean onDown(MotionEvent e) {
            Log.i(TAG, "onDown");
            sLastTouchAction = TOUCH_ACTION_TAP;
            mTotalDistanceX = 0;
            mTotalDistanceY = 0;
            return true;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {
        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.i(TAG, "onLongPress");
            sLastTouchAction = TOUCH_ACTION_PRESS_AND_HOLD;
        }

        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.i(TAG, "onScroll: mTotalDistanceX = " + mTotalDistanceX + ", mTotalDistanceY" + mTotalDistanceY + ", distanceX = " + distanceX + ", distanceY = " + distanceY);
            mTotalDistanceX += distanceX;
            mTotalDistanceY += distanceY;
            if (Math.abs(mTotalDistanceX) >= SCROLL_THRESHOLD || Math.abs(mTotalDistanceY) >= SCROLL_THRESHOLD) {
                Log.i(TAG, "onScroll: scrolled gesture");
                sLastTouchAction = TOUCH_ACTION_PAN;
            }
            return true;
        }
    });
    private View mTouchTestView;

    public static boolean isTouchTestActivityCreated() {
        return sInstance != null;
    }

    private static void finishTouchTestActivity() {
        if (sInstance != null) {
            sInstance.finish();
        }
    }

    public static void startTouchTestActivityHelper() {
        Log.i(TAG, "startTouchTestActivityHelper: ");
        Intent intent = new Intent(EolApplication.getAppContext(), TouchTestActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        EolApplication.getAppContext().startActivity(intent);
    }

    public static void handleGetMultiPoints(int id) {
        Log.i(TAG, "handleGetMultiPoints: id " + id);
        byte[] resBytes = new byte[21];
        resBytes[0] = Constants.VAL_0X00;
        for (int i = 0; i < MULTI_POINTER_COUNT; i++) {
            int x = (int) sMultiPoints.get(i).x;
            int y = (int) sMultiPoints.get(i).y;
            byte[] xBytes = Util.intTo2Byte(x);
            resBytes[i * 4 + 1] = xBytes[0];
            resBytes[i * 4 + 2] = xBytes[1];
            byte[] yBytes = Util.intTo2Byte(y);
            resBytes[i * 4 + 3] = yBytes[0];
            resBytes[i * 4 + 4] = yBytes[1];
            Log.i(TAG, "handleGetMultiPoints: i = " + i + ", x = " + x + ", y = " + y + ", " + resBytes[i * 4 + 1] + ", " + resBytes[i * 4 + 2] + ", " + resBytes[i * 4 + 3] + ", " + resBytes[i * 4 + 4]);
        }

        Log.i(TAG, "handleGetMultiPoints: result bytes " + Arrays.toString(resBytes));
        Util.setByteProperty(id, resBytes);
    }

    public static void handleGetGesture(int id) {
        Log.i(TAG, "handleGetLastGesture: " + id);
        byte[] resBytes = new byte[2];
        resBytes[0] = Constants.VAL_0X00;
        switch (sLastTouchAction) {
            case TOUCH_ACTION_TAP:
                resBytes[1] = Constants.VAL_0X01;
                break;
            case TOUCH_ACTION_PRESS_AND_HOLD:
                resBytes[1] = Constants.VAL_0X02;
                break;
            case TOUCH_ACTION_PAN:
                resBytes[1] = Constants.VAL_0X03;
                break;
            default:
                resBytes[1] = Constants.VAL_0X00;
                break;
        }
        Log.i(TAG, "handleGetMultiPoints: result bytes " + Arrays.toString(resBytes));
        Util.setByteProperty(id, resBytes);
    }

    public static void handleSetEnterExitTestMode(int id, byte[] values) {
        Log.i(TAG, "handleStartGestureAndTouchTest: id");
        if (values.length < 1) {
            Log.e(TAG, "handleSetEnterExitTestMode: wrong length");
            Util.setByteProperty(id, false);
            return;
        }
        if (values[0] == Constants.VAL_0X01) {
            startTouchTestActivityHelper();
        } else {
            finishTouchTestActivity();
        }

        Util.setByteProperty(id, true);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_touch_test);

        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN);
        for (int i = 0; i < MULTI_POINTER_COUNT; i++) {
            sMultiPoints.add(new PointF(0.0f, 0.0f));
        }

        Log.i(TAG, "onCreate: ");
        mTouchTestView = findViewById(R.id.v_touch_test);
        mTouchTestView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                recordMultiTouchPosition(motionEvent);
                return mTouchGestureDetector.onTouchEvent(motionEvent);
            }
        });

        sInstance = this;
    }

    @Override
    protected void onDestroy() {
        Log.i(TAG, "onDestroy: ");
        sInstance = null;
        super.onDestroy();
    }

    private void recordMultiTouchPosition(MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                for (int i = 0; i < MULTI_POINTER_COUNT; i++) {
                    sMultiPoints.get(i).set(0, 0);
                }
                Log.e(TAG, "recordMultiTouchPosition: reset");
                Log.i(TAG, "recordMultiTouchPosition: down index = " + event.getActionIndex() + ", x = " + event.getX() + ", y = " + event.getY());
                sMultiPoints.get(0).x = event.getX();
                sMultiPoints.get(0).y = event.getY();
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                int index = event.getActionIndex();
                Log.i(TAG, "recordMultiTouchPosition: down index = " + event.getActionIndex() + ", x = " + event.getX(index) + ", y = " + event.getY(index));
                if (index < MULTI_POINTER_COUNT) {
                    sMultiPoints.get(index).x = event.getX(index);
                    sMultiPoints.get(index).y = event.getY(index);
                }
                break;
            default:
                break;
        }
    }

}
